package com.qf.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.dao.DrugOrderMapper;
import com.qf.dao.MedicleSeckillDrugMapper;

import com.qf.pojo.entity.MedicleOrder;
import com.qf.pojo.entity.MedicleOrderitem;
import com.qf.pojo.entity.MedicleSeckilldrug;

import com.qf.pojo.req.PayReq;
import com.qf.pojo.resp.Resultmsg;
import com.qf.service.PayService;
import com.qf.strategy.PayFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @ClassName PayServiceImpl
 * @Description
 * @Author lanzhike
 * @Date 2023/7/30 20:40
 * @Version 1.0
 */
@Service
public class PayServiceImpl implements PayService {

    @Autowired
    PayFactory payFactory;
    @Autowired
    DrugOrderMapper drugOrderMapper;
    @Autowired
    MedicleSeckillDrugMapper seckillDrugMapper;
    @Override
    public Resultmsg pay(PayReq payReq) {
        Resultmsg pay = payFactory.pay(payReq);
        return pay;
    }

    @Override
    public void notifyUrl(HttpServletRequest request) {
        Map<String, String> stringStringMap = convertRequestParamsToMap(request);
        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(stringStringMap, "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApMXB58Hysr/wxwECPiQRhsLxP5cDQ9QjbJDigwDxf4pIX6duTiXVfcTNR70yFIuTn/8il1xy5mr4ydU3DrregW0QM7n/mYT/HjS2HK2sE/WW2SWHOyXARXq/7ggctoZI32hhd+2+LMVVnE7o1rNko2AzvJo6YTEQtZB+w15w+SAARkAtwVn0pdbCLZtHd1qGHUd7JUSeN2t7/UW+FEWSzVSMvM4F0uQDL0PMEEaVKd5pJ+9o2xCEpYbzEXPg1CY586SjX9eJcVSDIGQn5fHH7t9sClYmA8OooKVMKc3Hv1Ase+FpjZcUkYYyC/pEQkifScJ1ABHczE8DRUsDcDCO1wIDAQAB", "utf-8", "RSA2");
            if(signVerified){
                // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
                //校验1.订单号是否存在。2.支付金额是否匹配。3.支付宝返回的结果是否未成功
                String out_trade_no = stringStringMap.get("out_trade_no");
                String total_amount = stringStringMap.get("total_amount");
                String trade_status = stringStringMap.get("trade_status");
                if (trade_status.equals("TRADE_SUCCESS")){
                    //根据流水号查询订单信息
                    QueryWrapper<MedicleOrder> tbSeckillOrderQueryWrapper = new QueryWrapper<>();
                    tbSeckillOrderQueryWrapper.eq("transaction_id",out_trade_no);
                    MedicleOrder tbSeckillOrder = drugOrderMapper.selectOne(tbSeckillOrderQueryWrapper);
                    //比较支付的金额
                    if (tbSeckillOrder.getOrderMoney().compareTo(String.valueOf(Double.valueOf(total_amount)))==0){
                        //修改订单状态，减去具体的数据库的秒杀商品的库存数量
                        tbSeckillOrder.setOrderStatus("1");
                        tbSeckillOrder.setPayTime(new Date());
                        drugOrderMapper.updateById(tbSeckillOrder);
                        //获取秒杀id
                        List<MedicleOrderitem> orderItems = tbSeckillOrder.getOrderItems();
                        for (MedicleOrderitem orderItem : orderItems) {
                            Integer drugId = orderItem.getDrugId();
                            MedicleSeckilldrug seckilldrug = seckillDrugMapper.selectById(drugId);
                            seckilldrug.setSeckillDrugnum(seckilldrug.getSeckillDrugnum()-1);
                            seckillDrugMapper.updateById(seckilldrug);
                        }

                    }
                }

            }else{
                // TODO 验签失败则记录异常日志，并在response中返回failure.
                System.out.println("验签失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

    }

    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }
}
